//===----------------------------------------------------------------------===//
//
// This source file is part of the Soto for AWS open source project
//
// Copyright (c) 2017-2022 the Soto project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of Soto project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

// THIS FILE IS AUTOMATICALLY GENERATED by https://github.com/soto-project/soto-codegenerator.
// DO NOT EDIT.

@_exported import SotoCore

/// Service object for interacting with AWS Signer service.
///
/// AWS Signer is a fully managed code signing service to help you ensure the trust and
/// 			integrity of your code.
/// 		       AWS Signer supports the following applications:
/// 		       With code signing for AWS Lambda, you can sign AWS Lambda
/// 			deployment packages. Integrated support is provided for Amazon S3, Amazon CloudWatch,
/// 			and AWS CloudTrail. In order to sign code, you create a signing profile and then use
/// 			Signer to sign Lambda zip files in S3.
///
/// 		       With code signing for IoT, you can sign code for any IoT device that is
/// 			supported by AWS. IoT code signing is available for Amazon FreeRTOS and AWS IoT Device Management, and is
/// 			integrated with AWS Certificate Manager (ACM). In order to sign
/// 			code, you import a third-party code signing certificate using ACM, and use that to
/// 			sign updates in Amazon FreeRTOS and AWS IoT Device Management.
/// 		       For more information about AWS Signer, see the AWS Signer Developer Guide.
///
///
public struct Signer: AWSService {
    // MARK: Member variables

    /// Client used for communication with AWS
    public let client: AWSClient
    /// Service configuration
    public let config: AWSServiceConfig

    // MARK: Initialization

    /// Initialize the Signer client
    /// - parameters:
    ///     - client: AWSClient used to process requests
    ///     - region: Region of server you want to communicate with. This will override the partition parameter.
    ///     - partition: AWS partition where service resides, standard (.aws), china (.awscn), government (.awsusgov).
    ///     - endpoint: Custom endpoint URL to use instead of standard AWS servers
    ///     - timeout: Timeout value for HTTP requests
    public init(
        client: AWSClient,
        region: SotoCore.Region? = nil,
        partition: AWSPartition = .aws,
        endpoint: String? = nil,
        timeout: TimeAmount? = nil,
        byteBufferAllocator: ByteBufferAllocator = ByteBufferAllocator(),
        options: AWSServiceConfig.Options = []
    ) {
        self.client = client
        self.config = AWSServiceConfig(
            region: region,
            partition: region?.partition ?? partition,
            service: "signer",
            serviceProtocol: .restjson,
            apiVersion: "2017-08-25",
            endpoint: endpoint,
            errorType: SignerErrorType.self,
            timeout: timeout,
            byteBufferAllocator: byteBufferAllocator,
            options: options
        )
    }

    // MARK: API Calls

    /// Adds cross-account permissions to a signing profile.
    public func addProfilePermission(_ input: AddProfilePermissionRequest, logger: Logger = AWSClient.loggingDisabled, on eventLoop: EventLoop? = nil) -> EventLoopFuture<AddProfilePermissionResponse> {
        return self.client.execute(operation: "AddProfilePermission", path: "/signing-profiles/{profileName}/permissions", httpMethod: .POST, serviceConfig: self.config, input: input, logger: logger, on: eventLoop)
    }

    /// Changes the state of an ACTIVE signing profile to CANCELED.
    /// 			A canceled profile is still viewable with the ListSigningProfiles
    /// 			operation, but it cannot perform new signing jobs, and is deleted two years after
    /// 			cancelation.
    @discardableResult public func cancelSigningProfile(_ input: CancelSigningProfileRequest, logger: Logger = AWSClient.loggingDisabled, on eventLoop: EventLoop? = nil) -> EventLoopFuture<Void> {
        return self.client.execute(operation: "CancelSigningProfile", path: "/signing-profiles/{profileName}", httpMethod: .DELETE, serviceConfig: self.config, input: input, logger: logger, on: eventLoop)
    }

    /// Returns information about a specific code signing job. You specify the job by using
    /// 			the jobId value that is returned by the StartSigningJob
    /// 			operation.
    public func describeSigningJob(_ input: DescribeSigningJobRequest, logger: Logger = AWSClient.loggingDisabled, on eventLoop: EventLoop? = nil) -> EventLoopFuture<DescribeSigningJobResponse> {
        return self.client.execute(operation: "DescribeSigningJob", path: "/signing-jobs/{jobId}", httpMethod: .GET, serviceConfig: self.config, input: input, logger: logger, on: eventLoop)
    }

    /// Returns information on a specific signing platform.
    public func getSigningPlatform(_ input: GetSigningPlatformRequest, logger: Logger = AWSClient.loggingDisabled, on eventLoop: EventLoop? = nil) -> EventLoopFuture<GetSigningPlatformResponse> {
        return self.client.execute(operation: "GetSigningPlatform", path: "/signing-platforms/{platformId}", httpMethod: .GET, serviceConfig: self.config, input: input, logger: logger, on: eventLoop)
    }

    /// Returns information on a specific signing profile.
    public func getSigningProfile(_ input: GetSigningProfileRequest, logger: Logger = AWSClient.loggingDisabled, on eventLoop: EventLoop? = nil) -> EventLoopFuture<GetSigningProfileResponse> {
        return self.client.execute(operation: "GetSigningProfile", path: "/signing-profiles/{profileName}", httpMethod: .GET, serviceConfig: self.config, input: input, logger: logger, on: eventLoop)
    }

    /// Lists the cross-account permissions associated with a signing profile.
    public func listProfilePermissions(_ input: ListProfilePermissionsRequest, logger: Logger = AWSClient.loggingDisabled, on eventLoop: EventLoop? = nil) -> EventLoopFuture<ListProfilePermissionsResponse> {
        return self.client.execute(operation: "ListProfilePermissions", path: "/signing-profiles/{profileName}/permissions", httpMethod: .GET, serviceConfig: self.config, input: input, logger: logger, on: eventLoop)
    }

    /// Lists all your signing jobs. You can use the maxResults parameter to
    /// 			limit the number of signing jobs that are returned in the response. If additional jobs
    /// 			remain to be listed, code signing returns a nextToken value. Use this value in
    /// 			subsequent calls to ListSigningJobs to fetch the remaining values. You can
    /// 			continue calling ListSigningJobs with your maxResults
    /// 			parameter and with new values that code signing returns in the nextToken
    /// 			parameter until all of your signing jobs have been returned.
    public func listSigningJobs(_ input: ListSigningJobsRequest, logger: Logger = AWSClient.loggingDisabled, on eventLoop: EventLoop? = nil) -> EventLoopFuture<ListSigningJobsResponse> {
        return self.client.execute(operation: "ListSigningJobs", path: "/signing-jobs", httpMethod: .GET, serviceConfig: self.config, input: input, logger: logger, on: eventLoop)
    }

    /// Lists all signing platforms available in code signing that match the request parameters. If
    /// 			additional jobs remain to be listed, code signing returns a nextToken value. Use
    /// 			this value in subsequent calls to ListSigningJobs to fetch the remaining
    /// 			values. You can continue calling ListSigningJobs with your
    /// 				maxResults parameter and with new values that code signing returns in the
    /// 				nextToken parameter until all of your signing jobs have been
    /// 			returned.
    public func listSigningPlatforms(_ input: ListSigningPlatformsRequest, logger: Logger = AWSClient.loggingDisabled, on eventLoop: EventLoop? = nil) -> EventLoopFuture<ListSigningPlatformsResponse> {
        return self.client.execute(operation: "ListSigningPlatforms", path: "/signing-platforms", httpMethod: .GET, serviceConfig: self.config, input: input, logger: logger, on: eventLoop)
    }

    /// Lists all available signing profiles in your AWS account. Returns only profiles with
    /// 			an ACTIVE status unless the includeCanceled request field is
    /// 			set to true. If additional jobs remain to be listed, code signing returns a
    /// 				nextToken value. Use this value in subsequent calls to
    /// 				ListSigningJobs to fetch the remaining values. You can continue calling
    /// 				ListSigningJobs with your maxResults parameter and with
    /// 			new values that code signing returns in the nextToken parameter until all of your
    /// 			signing jobs have been returned.
    public func listSigningProfiles(_ input: ListSigningProfilesRequest, logger: Logger = AWSClient.loggingDisabled, on eventLoop: EventLoop? = nil) -> EventLoopFuture<ListSigningProfilesResponse> {
        return self.client.execute(operation: "ListSigningProfiles", path: "/signing-profiles", httpMethod: .GET, serviceConfig: self.config, input: input, logger: logger, on: eventLoop)
    }

    /// Returns a list of the tags associated with a signing profile resource.
    public func listTagsForResource(_ input: ListTagsForResourceRequest, logger: Logger = AWSClient.loggingDisabled, on eventLoop: EventLoop? = nil) -> EventLoopFuture<ListTagsForResourceResponse> {
        return self.client.execute(operation: "ListTagsForResource", path: "/tags/{resourceArn}", httpMethod: .GET, serviceConfig: self.config, input: input, logger: logger, on: eventLoop)
    }

    /// Creates a signing profile. A signing profile is a code signing template that can be used to
    /// 			carry out a pre-defined signing job. For more information, see http://docs.aws.amazon.com/signer/latest/developerguide/gs-profile.html
    public func putSigningProfile(_ input: PutSigningProfileRequest, logger: Logger = AWSClient.loggingDisabled, on eventLoop: EventLoop? = nil) -> EventLoopFuture<PutSigningProfileResponse> {
        return self.client.execute(operation: "PutSigningProfile", path: "/signing-profiles/{profileName}", httpMethod: .PUT, serviceConfig: self.config, input: input, logger: logger, on: eventLoop)
    }

    /// Removes cross-account permissions from a signing profile.
    public func removeProfilePermission(_ input: RemoveProfilePermissionRequest, logger: Logger = AWSClient.loggingDisabled, on eventLoop: EventLoop? = nil) -> EventLoopFuture<RemoveProfilePermissionResponse> {
        return self.client.execute(operation: "RemoveProfilePermission", path: "/signing-profiles/{profileName}/permissions/{statementId}", httpMethod: .DELETE, serviceConfig: self.config, input: input, logger: logger, on: eventLoop)
    }

    /// Changes the state of a signing job to REVOKED. This indicates that the signature is no
    /// 			longer valid.
    @discardableResult public func revokeSignature(_ input: RevokeSignatureRequest, logger: Logger = AWSClient.loggingDisabled, on eventLoop: EventLoop? = nil) -> EventLoopFuture<Void> {
        return self.client.execute(operation: "RevokeSignature", path: "/signing-jobs/{jobId}/revoke", httpMethod: .PUT, serviceConfig: self.config, input: input, logger: logger, on: eventLoop)
    }

    /// Changes the state of a signing profile to REVOKED. This indicates that signatures
    /// 			generated using the signing profile after an effective start date are no longer
    /// 			valid.
    @discardableResult public func revokeSigningProfile(_ input: RevokeSigningProfileRequest, logger: Logger = AWSClient.loggingDisabled, on eventLoop: EventLoop? = nil) -> EventLoopFuture<Void> {
        return self.client.execute(operation: "RevokeSigningProfile", path: "/signing-profiles/{profileName}/revoke", httpMethod: .PUT, serviceConfig: self.config, input: input, logger: logger, on: eventLoop)
    }

    /// Initiates a signing job to be performed on the code provided. Signing jobs are
    /// 			viewable by the ListSigningJobs operation for two years after they are
    /// 			performed. Note the following requirements:
    ///
    /// 				            You must create an Amazon S3 source bucket. For more information, see Create a Bucket in the
    /// 						Amazon S3 Getting Started Guide.
    ///
    /// 				           Your S3 source bucket must be version enabled.
    ///
    /// 				           You must create an S3 destination bucket. Code signing uses your S3 destination
    /// 					bucket to write your signed code.
    ///
    /// 				           You specify the name of the source and destination buckets when calling the
    /// 						StartSigningJob operation.
    ///
    /// 				           You must also specify a request token that identifies your request to
    /// 					code signing.
    ///
    /// 		       You can call the DescribeSigningJob and the ListSigningJobs actions after you call
    /// 			StartSigningJob.
    /// 		       For a Java example that shows how to use this action, see http://docs.aws.amazon.com/acm/latest/userguide/
    public func startSigningJob(_ input: StartSigningJobRequest, logger: Logger = AWSClient.loggingDisabled, on eventLoop: EventLoop? = nil) -> EventLoopFuture<StartSigningJobResponse> {
        return self.client.execute(operation: "StartSigningJob", path: "/signing-jobs", httpMethod: .POST, serviceConfig: self.config, input: input, logger: logger, on: eventLoop)
    }

    /// Adds one or more tags to a signing profile. Tags are labels that you can use to
    /// 			identify and organize your AWS resources. Each tag consists of a key and an optional
    /// 			value. To specify the signing profile, use its Amazon Resource Name (ARN). To specify
    /// 			the tag, use a key-value pair.
    public func tagResource(_ input: TagResourceRequest, logger: Logger = AWSClient.loggingDisabled, on eventLoop: EventLoop? = nil) -> EventLoopFuture<TagResourceResponse> {
        return self.client.execute(operation: "TagResource", path: "/tags/{resourceArn}", httpMethod: .POST, serviceConfig: self.config, input: input, logger: logger, on: eventLoop)
    }

    /// Removes one or more tags from a signing profile. To remove the tags, specify a list of
    /// 			tag keys.
    public func untagResource(_ input: UntagResourceRequest, logger: Logger = AWSClient.loggingDisabled, on eventLoop: EventLoop? = nil) -> EventLoopFuture<UntagResourceResponse> {
        return self.client.execute(operation: "UntagResource", path: "/tags/{resourceArn}", httpMethod: .DELETE, serviceConfig: self.config, input: input, logger: logger, on: eventLoop)
    }
}

extension Signer {
    /// Initializer required by `AWSService.with(middlewares:timeout:byteBufferAllocator:options)`. You are not able to use this initializer directly as there are no public
    /// initializers for `AWSServiceConfig.Patch`. Please use `AWSService.with(middlewares:timeout:byteBufferAllocator:options)` instead.
    public init(from: Signer, patch: AWSServiceConfig.Patch) {
        self.client = from.client
        self.config = from.config.with(patch: patch)
    }
}

// MARK: Paginators

extension Signer {
    ///  Lists all your signing jobs. You can use the maxResults parameter to
    ///  			limit the number of signing jobs that are returned in the response. If additional jobs
    ///  			remain to be listed, code signing returns a nextToken value. Use this value in
    ///  			subsequent calls to ListSigningJobs to fetch the remaining values. You can
    ///  			continue calling ListSigningJobs with your maxResults
    ///  			parameter and with new values that code signing returns in the nextToken
    ///  			parameter until all of your signing jobs have been returned.
    ///
    /// Provide paginated results to closure `onPage` for it to combine them into one result.
    /// This works in a similar manner to `Array.reduce<Result>(_:_:) -> Result`.
    ///
    /// Parameters:
    ///   - input: Input for request
    ///   - initialValue: The value to use as the initial accumulating value. `initialValue` is passed to `onPage` the first time it is called.
    ///   - logger: Logger used flot logging
    ///   - eventLoop: EventLoop to run this process on
    ///   - onPage: closure called with each paginated response. It combines an accumulating result with the contents of response. This combined result is then returned
    ///         along with a boolean indicating if the paginate operation should continue.
    public func listSigningJobsPaginator<Result>(
        _ input: ListSigningJobsRequest,
        _ initialValue: Result,
        logger: Logger = AWSClient.loggingDisabled,
        on eventLoop: EventLoop? = nil,
        onPage: @escaping (Result, ListSigningJobsResponse, EventLoop) -> EventLoopFuture<(Bool, Result)>
    ) -> EventLoopFuture<Result> {
        return self.client.paginate(
            input: input,
            initialValue: initialValue,
            command: self.listSigningJobs,
            inputKey: \ListSigningJobsRequest.nextToken,
            outputKey: \ListSigningJobsResponse.nextToken,
            on: eventLoop,
            onPage: onPage
        )
    }

    /// Provide paginated results to closure `onPage`.
    ///
    /// - Parameters:
    ///   - input: Input for request
    ///   - logger: Logger used flot logging
    ///   - eventLoop: EventLoop to run this process on
    ///   - onPage: closure called with each block of entries. Returns boolean indicating whether we should continue.
    public func listSigningJobsPaginator(
        _ input: ListSigningJobsRequest,
        logger: Logger = AWSClient.loggingDisabled,
        on eventLoop: EventLoop? = nil,
        onPage: @escaping (ListSigningJobsResponse, EventLoop) -> EventLoopFuture<Bool>
    ) -> EventLoopFuture<Void> {
        return self.client.paginate(
            input: input,
            command: self.listSigningJobs,
            inputKey: \ListSigningJobsRequest.nextToken,
            outputKey: \ListSigningJobsResponse.nextToken,
            on: eventLoop,
            onPage: onPage
        )
    }

    ///  Lists all signing platforms available in code signing that match the request parameters. If
    ///  			additional jobs remain to be listed, code signing returns a nextToken value. Use
    ///  			this value in subsequent calls to ListSigningJobs to fetch the remaining
    ///  			values. You can continue calling ListSigningJobs with your
    ///  				maxResults parameter and with new values that code signing returns in the
    ///  				nextToken parameter until all of your signing jobs have been
    ///  			returned.
    ///
    /// Provide paginated results to closure `onPage` for it to combine them into one result.
    /// This works in a similar manner to `Array.reduce<Result>(_:_:) -> Result`.
    ///
    /// Parameters:
    ///   - input: Input for request
    ///   - initialValue: The value to use as the initial accumulating value. `initialValue` is passed to `onPage` the first time it is called.
    ///   - logger: Logger used flot logging
    ///   - eventLoop: EventLoop to run this process on
    ///   - onPage: closure called with each paginated response. It combines an accumulating result with the contents of response. This combined result is then returned
    ///         along with a boolean indicating if the paginate operation should continue.
    public func listSigningPlatformsPaginator<Result>(
        _ input: ListSigningPlatformsRequest,
        _ initialValue: Result,
        logger: Logger = AWSClient.loggingDisabled,
        on eventLoop: EventLoop? = nil,
        onPage: @escaping (Result, ListSigningPlatformsResponse, EventLoop) -> EventLoopFuture<(Bool, Result)>
    ) -> EventLoopFuture<Result> {
        return self.client.paginate(
            input: input,
            initialValue: initialValue,
            command: self.listSigningPlatforms,
            inputKey: \ListSigningPlatformsRequest.nextToken,
            outputKey: \ListSigningPlatformsResponse.nextToken,
            on: eventLoop,
            onPage: onPage
        )
    }

    /// Provide paginated results to closure `onPage`.
    ///
    /// - Parameters:
    ///   - input: Input for request
    ///   - logger: Logger used flot logging
    ///   - eventLoop: EventLoop to run this process on
    ///   - onPage: closure called with each block of entries. Returns boolean indicating whether we should continue.
    public func listSigningPlatformsPaginator(
        _ input: ListSigningPlatformsRequest,
        logger: Logger = AWSClient.loggingDisabled,
        on eventLoop: EventLoop? = nil,
        onPage: @escaping (ListSigningPlatformsResponse, EventLoop) -> EventLoopFuture<Bool>
    ) -> EventLoopFuture<Void> {
        return self.client.paginate(
            input: input,
            command: self.listSigningPlatforms,
            inputKey: \ListSigningPlatformsRequest.nextToken,
            outputKey: \ListSigningPlatformsResponse.nextToken,
            on: eventLoop,
            onPage: onPage
        )
    }

    ///  Lists all available signing profiles in your AWS account. Returns only profiles with
    ///  			an ACTIVE status unless the includeCanceled request field is
    ///  			set to true. If additional jobs remain to be listed, code signing returns a
    ///  				nextToken value. Use this value in subsequent calls to
    ///  				ListSigningJobs to fetch the remaining values. You can continue calling
    ///  				ListSigningJobs with your maxResults parameter and with
    ///  			new values that code signing returns in the nextToken parameter until all of your
    ///  			signing jobs have been returned.
    ///
    /// Provide paginated results to closure `onPage` for it to combine them into one result.
    /// This works in a similar manner to `Array.reduce<Result>(_:_:) -> Result`.
    ///
    /// Parameters:
    ///   - input: Input for request
    ///   - initialValue: The value to use as the initial accumulating value. `initialValue` is passed to `onPage` the first time it is called.
    ///   - logger: Logger used flot logging
    ///   - eventLoop: EventLoop to run this process on
    ///   - onPage: closure called with each paginated response. It combines an accumulating result with the contents of response. This combined result is then returned
    ///         along with a boolean indicating if the paginate operation should continue.
    public func listSigningProfilesPaginator<Result>(
        _ input: ListSigningProfilesRequest,
        _ initialValue: Result,
        logger: Logger = AWSClient.loggingDisabled,
        on eventLoop: EventLoop? = nil,
        onPage: @escaping (Result, ListSigningProfilesResponse, EventLoop) -> EventLoopFuture<(Bool, Result)>
    ) -> EventLoopFuture<Result> {
        return self.client.paginate(
            input: input,
            initialValue: initialValue,
            command: self.listSigningProfiles,
            inputKey: \ListSigningProfilesRequest.nextToken,
            outputKey: \ListSigningProfilesResponse.nextToken,
            on: eventLoop,
            onPage: onPage
        )
    }

    /// Provide paginated results to closure `onPage`.
    ///
    /// - Parameters:
    ///   - input: Input for request
    ///   - logger: Logger used flot logging
    ///   - eventLoop: EventLoop to run this process on
    ///   - onPage: closure called with each block of entries. Returns boolean indicating whether we should continue.
    public func listSigningProfilesPaginator(
        _ input: ListSigningProfilesRequest,
        logger: Logger = AWSClient.loggingDisabled,
        on eventLoop: EventLoop? = nil,
        onPage: @escaping (ListSigningProfilesResponse, EventLoop) -> EventLoopFuture<Bool>
    ) -> EventLoopFuture<Void> {
        return self.client.paginate(
            input: input,
            command: self.listSigningProfiles,
            inputKey: \ListSigningProfilesRequest.nextToken,
            outputKey: \ListSigningProfilesResponse.nextToken,
            on: eventLoop,
            onPage: onPage
        )
    }
}

extension Signer.ListSigningJobsRequest: AWSPaginateToken {
    public func usingPaginationToken(_ token: String) -> Signer.ListSigningJobsRequest {
        return .init(
            isRevoked: self.isRevoked,
            jobInvoker: self.jobInvoker,
            maxResults: self.maxResults,
            nextToken: token,
            platformId: self.platformId,
            requestedBy: self.requestedBy,
            signatureExpiresAfter: self.signatureExpiresAfter,
            signatureExpiresBefore: self.signatureExpiresBefore,
            status: self.status
        )
    }
}

extension Signer.ListSigningPlatformsRequest: AWSPaginateToken {
    public func usingPaginationToken(_ token: String) -> Signer.ListSigningPlatformsRequest {
        return .init(
            category: self.category,
            maxResults: self.maxResults,
            nextToken: token,
            partner: self.partner,
            target: self.target
        )
    }
}

extension Signer.ListSigningProfilesRequest: AWSPaginateToken {
    public func usingPaginationToken(_ token: String) -> Signer.ListSigningProfilesRequest {
        return .init(
            includeCanceled: self.includeCanceled,
            maxResults: self.maxResults,
            nextToken: token,
            platformId: self.platformId,
            statuses: self.statuses
        )
    }
}

// MARK: Waiters

extension Signer {
    public func waitUntilSuccessfulSigningJob(
        _ input: DescribeSigningJobRequest,
        maxWaitTime: TimeAmount? = nil,
        logger: Logger = AWSClient.loggingDisabled,
        on eventLoop: EventLoop? = nil
    ) -> EventLoopFuture<Void> {
        let waiter = AWSClient.Waiter(
            acceptors: [
                .init(state: .success, matcher: try! JMESPathMatcher("status", expected: "Succeeded")),
                .init(state: .failure, matcher: try! JMESPathMatcher("status", expected: "Failed")),
                .init(state: .failure, matcher: AWSErrorCodeMatcher("ResourceNotFoundException")),
            ],
            minDelayTime: .seconds(20),
            command: self.describeSigningJob
        )
        return self.client.waitUntil(input, waiter: waiter, maxWaitTime: maxWaitTime, logger: logger, on: eventLoop)
    }
}
